<!-- 
  watch()
    语法：
      watch(要监听的数据源, 监听的回调函数, 一些额外配置项)

      要监听的数据源：
        1. 可以直接是一个 ref 数据
        2. 可以直接是一个 reactive 数据，会自动开启 deep (不推荐)
          1. 如果只是想要监听 reactive 的某个属性的变化的话，可以使用 () => xxx.xxx
          2. newValue 与 oldValue 无法分辨出数据的变动
        3. 可以是一个函数返回一个 reactive 数据某个属性的形式
        4. 上面三种类型组成的数组的形式

      一些额外配置项
        deep        是否开启深度监听
        immediate   是否默认触发回调函数一次
        flush       回调函数的触发时机的控制
          - pre     默认值，触发时机在 DOM 更新之前
          - post    触发实际 在 DOM 更新之后
          - sync    ......

  watchEffect()
    作用：立即执行回调函数，且会将回调函数中用到的响应式数据收集为依赖，当依赖变化时回调函数会再次触发
    语法：
      const stop = watchEffect(effect回调函数, 配置项)
        stop 是个函数，调用它的话，可以停止该 watchEffect

        effect回调函数，它会收到一个函数（onClearUp - 清理函数）作为参数

        onClearUp(clearUp)



  watch 与 watchEffect 的区别有哪些：
    1. watch 默认是懒执行，不会默认触发一次，而 watchEffect 会默认触发一次
    2. watch 可以更明确的知道是监听的那个数据
    3. watch 可以获取到监听数据的新值与旧值。
 -->

<template>
  <div>
    <h1>App</h1>
    <button id="box" @click="count++">{{ count }}</button>

    <button @click="state.name += '~'">{{ state.name }}</button>
    <button @click="state.address.city = '广州市'">{{ state.address.city }}</button>

    <button @click="stop">stop</button>

    <hr />

    <input type="text" v-model="value" />
    <hr />
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { reactive, ref, watch, watchEffect } from 'vue'
import axios from 'axios'

export default {
  setup() {
    const count = ref(10)
    const state = reactive({
      name: '张胜男',
      age: 18,
      address: {
        city: '深圳市',
      },
    })

    /**
     * 1. effect 回调函数，默认触发一次，这时 清理回调函数不会触发
     * 2. 后续当 effect 回调函数要触发之前，会先触发上一次的 清理回调函数
     */
    // const stop = watchEffect((onClearUp) => {
    //   console.log('effect 回调函数', count.value)

    //   // 调用onClearUp注册清理回调
    //   onClearUp(() => {
    //     console.log('清理回调函数')
    //   })
    // })

    watchEffect((onClearUp) => {
      console.log(count.value)

      function handleClick() {
        console.log('点击了')
      }

      window.addEventListener('click', handleClick)

      // 注册清理回调
      onClearUp(() => {
        window.removeEventListener('click', handleClick)
      })
    })

    // 搜索关键字
    const value = ref('')
    const list = ref([])

    watchEffect((onClearUp) => {
      console.log('111')
      const keyword = value.value

      const timer = setTimeout(() => {
        // 调用接口
        axios.get('http://localhost:3000/books?name_like=' + keyword).then((response) => {
          console.log(response)
          list.value = response.data
        })
      }, 500)

      // 注册清理回调
      onClearUp(() => {
        clearTimeout(timer)
      })
    })

    watchEffect((onClearUp) => {
      console.log('hello hello', count.value)

      const timer = setInterval(() => {
        // PS: count 的使用放置在异步代码中，不会被当前的 watchEffect 给收集为依赖
        console.log('setInterval')
      }, 1000)

      // 注册清理回调
      onClearUp(() => {
        clearInterval(timer)
      })
    })

    return {
      count,
      state,
      stop,
      value,
      list,
    }
  },

  // setup() {
  //   const count = ref(10)
  //   // 监听 ref 数据
  //   watch(
  //     count,
  //     (newValue, oldValue) => {
  //       console.log('count 改变了', newValue, oldValue)
  //       console.log(document.querySelector('#box')?.innerHTML)
  //     },
  //     {
  //       immediate: true, // 默认触发一次
  //       flush: 'sync', // 在DOM更新之后再触发 监听回调
  //     }
  //   )
  //   const state = reactive({
  //     name: '张三',
  //     age: 18,
  //     address: {
  //       city: '深圳市',
  //     },
  //   })
  //   // 监听 reactive 数据
  //   // watch(state, (newValue, oldValue) => {
  //   //   console.log('state 改变了', newValue, oldValue)
  //   // })
  //   // 直接监听 reactive 中某个属性的变化
  //   //    不能直接写 state.name
  //   //        需要： () => state.name
  //   // watch(
  //   //   () => state.name,
  //   //   (newValue, oldValue) => {
  //   //     console.log('state.name 改变了', newValue, oldValue)
  //   //   }
  //   // )
  //   // 监听一个数组，数组中是 ref、reactive、() =>
  //   // watch([count, () => state.name], (newValue, oldValue) => {
  //   //   console.log('改变了', newValue, oldValue)
  //   // })
  //   return {
  //     count,
  //     state,
  //   }
  // },
}
</script>
